/*
 * Master_Controller.c
 *
 * Created: 6/3/2013 8:11:08 PM
 *  Author: Crossfire
 */ 

#include "Master_Controller.h"

int main(void)
{
	Init();
	_delay_ms(2000);
    while(1)
    {
		GetUart();
		_delay_ms(2);
		Set_Modus();
		_delay_ms(2);
		Set_Streetlights();
		_delay_ms(2);
	}    
}

///Functie voor straatverlichting
void Set_Streetlights(void)
{
	if((PINA & (1<<PINA1)) == 0)
	{
		PORTB |= (1 << PORTB0);
	}
	else
	{
		PORTB |= (0 << PORTB0);
	}
}

///Functie voor modus te zetten
void Set_Modus(void)
{
	if(_modus == 0 && (PINA & (1 << PINA0)) == 0)
	{
		_modus = 1;
	}
	else if(_modus == 1 && (PINA & (1 << PINA0)) != 0)
	{
		_modus = 0;
		//Als het modus 0 is moet de default data een keer worden verzonden, hiervoor is modus_send
		_modus_send = 0; 
	}
}

///Functie voor ontvangen uart
void GetUart(void)
{
	//Get uart data, als er een timeout is komt er -1 terug
	_receive = SERIAL_receiveByte(1000);
	_delay_ms(5);
	//Als de data niet -1 is maar de modus is 0 word er niks gedaan met de data, de data word wel gelezen om de buffer te legen
	if(_modus == 1 && _timeout != 1) 
	{
		//Als het wel modus een is en er is data ontvangen word dit geparsed
		parse_received_data(_receive); 		
	}
	//Als het modus 0 is moet de default data eenmalig worden verzonden, als modus_send 0 is kan dit verzonden worden daarna word modus_send weer 1 zodat het niet nog een keer verzonden word
	else if((_modus == 0) && (_modus_send == 0)) 
	{
		//Verzenden van dummy-default data naar TJunction
		////////Send_Default_data(TJUNCTION); 
		//Verzenden van dummy-default data naar Crossroad
		Send_Default_data(CROSSROAD); 
		//Data is verzonden, zorgen dat het niet dubbel verzonden word
		_modus_send = 1; 
	}
}

///functie om de ontvangen data op te slaan en uiteindelijk te verzenden
void parse_received_data(uint8_t data)
{
	//Ontvang data en zet het op de goede plaats in de array
	_data_array[_received_data_from_Uart] = data; 
	//send back to usart for check
	//SERIAL_sendByte(_received_data_from_Uart);
	//Hou bij hoeveel data er ontvangen is
	_received_data_from_Uart++;
	//PORTB = _received_data_from_Uart;
	_delay_ms(50);
	//Zijn er 57 bytes ontvangen ga dan verzenden
	if(_received_data_from_Uart == 57)
	{
		//Kijk of het Tjunction is of Crossroad
		if(_data_array[0] == 128)
			_address = TJUNCTION; 
		else if(_data_array[0] == 64)
			_address = CROSSROAD;
		for(int i = 0; i < 57; i++)
		{
			//verzend alle data
			TWI_Send(_data_array[i], _address); 
		}
		//reset aantal ontvangen data	
		_received_data_from_Uart = 0; 
	}
}

///functie om default data te verzenden naar slave op "address"
void Send_Default_data(uint8_t address)
{
	//Zend default herkennings byte
	if(address == TJUNCTION)
		TWI_Send(129, address); 
	else if(address == CROSSROAD)
		TWI_Send(65, address);
	//Zend nog 56 keer 0 zodat er in totaal 57 bytes verzonden zijn
	for(int i = 0; i < 56; i++) 
	{
		TWI_Send(0, address);
	}
}

///Functie om alles te initialiseren
void Init(void)
{
	//Initialiseren van switches
	DDRA = 0x00; 
	//Initialiseren van switches
	DDRB = 0xFF; 
	PORTB = 0;
	_delay_ms(1000);
	PORTB = ~0;
	//Modus begint op default
	_modus = 0; 
	//Nog niks ontvangen van uart
	_received_data_from_Uart = 0;
	_timeout = 0; 
	//Master TWI init
	TWI_init_master(); 
	//Serial uart init
	SERIAL_init(9600); 
}

///Functie om de master te initialiseren
void TWI_init_master(void) 
{
	// Bit rate
	TWBR=0x01;	
	//Zetten van prescalar bits
	TWSR=(0<<TWPS1)|(0<<TWPS0);	
	// SCL freq= F_CPU/(16+2(TWBR).4^TWPS)
}

///Functie om Two Wired Interface te starten
void TWI_start(void)
{
	//TWI interrupt flag wissen, Start conditie instellen op SDA, Inschakelen van TWI
	TWCR= (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
	//Wacht tot stat conditie is verzonden
	while(!(TWCR & (1<<TWINT)));
	//Controleer voor de bevestiging
	while((TWSR & 0xF8)!= 0x08);
}

///Functie om het slave andress te versturen
void TWI_write_address(unsigned char data)
{
	//Adress en schrijf instructie
	TWDR=data;
	//TWI interrupt flag wissen, TWI instellen
	TWCR=(1<<TWINT)|(1<<TWEN);
	//Wact tot complete TWDR byte is verstuurd
	while (!(TWCR & (1<<TWINT)));
	//Controleer voor de bevestiging
	while((TWSR & 0xF8)!= 0x18);
}

///Functie om te schrijven naar de slave
void TWI_write_data(unsigned char data)
{
	//Adress en schrijf instructie
	TWDR=data;	// put data in TWDR
	//TWI interrupt flag wissen, TWI instellen
	TWCR=(1<<TWINT)|(1<<TWEN);
	//Wacht tot complete TWDR byte is ontvangen
	while (!(TWCR & (1<<TWINT)));
	//Controleer voor de bevestiging
	while((TWSR & 0xF8) != 0x28);
}

///Functie voor het versturen van stop bit zodat het versturings process stopt
void TWI_stop(void)
{
	//TWI interrupt flag wissen, stop conditie instellen op SDA. TWI instellen
	TWCR= (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
	//Wacht tot stop conditie is verzonden
	while(!(TWCR & (1<<TWSTO)));  // Wait till stop condition is transmitted
}

///functie om een byte te verzenden naar een slave
void TWI_Send(uint8_t data, uint8_t address)
{
	TWI_start();
	TWI_write_address(address);
	TWI_write_data(data);
	TWI_stop();
	_delay_ms(5);
}

///Functie om de Uart te initialiseren
void SERIAL_init(unsigned int baudrate)
{
	//8UL vs 16UL omdat de U2X bit is enabled
	baudrate = F_CPU / (baudrate *8UL) -1;
	//Double speed operation enabled			
	UCSRA = (1<<U2X);								
	UCSRB = (1<<RXEN)|(1<<TXEN);
	//Gebruik 8 bit character grootte, 1 stopbit, geen parity
	UCSRC = (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);		
	UBRRL = baudrate;
	UBRRH = (baudrate >> 8);
}

///Uart ontvang functie timeout
int SERIAL_receiveByte(int timeout)
{
	int i = 0;
	while ((( UCSRA & (1 << RXC )) == 0) && (i <= timeout)) 
	{
		i++;
	}
	if (i >= timeout)
	{
		_timeout = 1;
		return 0;
	}	
	_timeout = 0;	
	return UDR ;
}

///Functie om Uart te versturen
void SERIAL_sendByte(unsigned int byte)
{
	while (( UCSRA & (1 << UDRE )) == 0);
	UDR = byte;
}